﻿using DocumentFormat.OpenXml.InkML;
using IDEAMS.core.opm;
using IDEAMS.core.queue;
using IDEAMS.model;
using IDEAMS.model.alarm;
using IDEAMS.model.continuous;
using log4net;
using System;
using System.IO;
using System.Text;


namespace IDEAMS.core.deviceClient
{
    public class ContinuousWorker : OPM_MsgWorker
    {
        private static ILog logger = LogManager.GetLogger(typeof(ContinuousWorker));

        private string serialNo;
        private string filePath;
        private StreamWriterWrapper sw;

        private DateTime nextRecordTime;
        private int deviceFrequency;

        public ContinuousWorker()
        {
            nextRecordTime = DateTime.Now;
            handleProc = ContinuousSaveProc;
            keyList.Add(QueueDataType.DATA_WL);

            TW_App.delegateCollection.connectionStatusChangeEvent += ConnectionStatusChangeEvent;
        }

        public ContinuousWorker(string serialNo) : this()
        {
            this.serialNo = serialNo;
        }

        /// <summary>
        /// 设备连接状态改变
        /// </summary>
        /// <param name="serialNo"></param>
        /// <param name="status"></param>
        private void ConnectionStatusChangeEvent(string serialNo, ConnectionStatus status)
        {
            
        }


        protected override int PreStart()
        {
            int rn = 0;

            filePath = string.Format(TW_App.fileManager.waveLenFile, serialNo);
            // 获取文件所在的目录路径
            string directoryPath = Path.GetDirectoryName(filePath);

            // 检查目录是否存在
            if (!Directory.Exists(directoryPath))
            {
                // 目录不存在，创建目录
                Directory.CreateDirectory(directoryPath);
            }

            CreateFileMode fileMode = new CreateFileMode();
            fileMode.createFileMode = EM_CreateFileMode.UNBOUND;
            sw = new StreamWriterWrapper(filePath, fileMode);

            this.startTime = DateTime.Now;
            deviceValue = null;

            return rn;
        }

        protected override int AfterStart()
        {
            if(sw != null)
            {
                sw.Close();
            }
            return 0;
        }

        public override void Start()
        {
            this.stopFlag = false;
            if(PreStart() == -1)
            {
                logger.WarnFormat("worker启动失败");
                goto end;
            }

            while (!stopFlag)
            {

                // 读取消息
                QueueData msg = null;
                bool rn2 = recvQueue.TryDequeue(out msg, 3000);
                if (!rn2)
                {
                    logger.WarnFormat("无数据");
                    continue;
                }

                ContinuousSaveProc(msg);
            }

        end:
            AfterStart();
            if(postProc != null)
            {
                postProc();
            }
        }

        public override void Stop()
        {
            this.stopFlag = true;
        }

        public void FrequencyTimeInit()
        {
            this.nextRecordTime = DateTime.Now;
        }

        private object locker = new object();
        private DeviceValue deviceValue;
        //int iiindex = 0;
        private void ContinuousSaveProc(QueueData msg)
        {
            //Console.WriteLine(iiindex);
            //DateTime sssTime = DateTime.Now;
            lock (locker)
            {
                try
                {
                    Wave wlData = (Wave)msg;
                    if (deviceValue == null)
                    {
                        deviceValue = new DeviceValue();
                        deviceValue.channelCount = wlData.nChannel;
                        deviceValue.channelValues = new ChannelValue[wlData.nChannel];

                        for (int i = 0; i < wlData.nChannel; i++)
                        {
                            deviceValue.channelValues[i] = new ChannelValue();
                            deviceValue.channelValues[i].gratingCount = wlData.chGratting[i].ngrating;
                            deviceValue.channelValues[i].gratingValues = new GratingValue[wlData.chGratting[i].ngrating];
                            if (wlData.chGratting[i].ngrating == 0) continue;

                            for (int j = 0; j < wlData.chGratting[i].waveValueArray.Length; j++)
                            {
                                deviceValue.channelValues[i].gratingValues[j] = new GratingValue();
                                deviceValue.channelValues[i].gratingValues[j].preValue = wlData.chGratting[i].waveValueArray[j];
                                deviceValue.channelValues[i].gratingValues[j].maxValue = wlData.chGratting[i].waveValueArray[j];
                                deviceValue.channelValues[i].gratingValues[j].minValue = wlData.chGratting[i].waveValueArray[j];
                            }
                        }
                    }
                    else
                    {
                        if (deviceValue.channelCount != wlData.nChannel)
                        {
                            AlarmInfo alarmInfo = new AlarmInfo();
                            alarmInfo.serialNo = serialNo;
                            alarmInfo.type = AlarmType.GRATING_COUNT_CHANGE;
                            alarmInfo.key = ProcessStep.CONTINUOUS_DETECTION + "_" + AlarmType.CHANNEL_COUNT_CHANGE;
                            alarmInfo.channelNo = 0;
                            alarmInfo.gratingNo = 0;
                            alarmInfo.step = ProcessStep.CONTINUOUS_DETECTION;
                            alarmInfo.maxDiff = deviceValue.channelCount - wlData.nChannel;
                            alarmInfo.startTime = DateTime.Now;
                            alarmInfo.endTime = DateTime.Now;
                            alarmInfo.description = string.Format("通道数由[{0}]个变成[{1}]个", deviceValue.channelCount, wlData.nChannel);
                            TW_App.delegateCollection.SyncAlarm(alarmInfo);

                        }
                        else
                        {
                            for (int i = 0; i < wlData.nChannel; i++)
                            {
                                if (deviceValue.channelValues[i].gratingCount != wlData.chGratting[i].ngrating)
                                {
                                    AlarmInfo alarmInfo = new AlarmInfo();
                                    alarmInfo.serialNo = serialNo;
                                    alarmInfo.type = AlarmType.GRATING_COUNT_CHANGE;
                                    alarmInfo.key = (i + 1) + "_" + ProcessStep.CONTINUOUS_DETECTION + "_" + AlarmType.GRATING_COUNT_CHANGE;
                                    alarmInfo.channelNo = (i + 1);
                                    alarmInfo.gratingNo = 0;
                                    alarmInfo.step = ProcessStep.CONTINUOUS_DETECTION;
                                    alarmInfo.maxDiff = deviceValue.channelValues[i].gratingCount - wlData.chGratting[i].ngrating;
                                    alarmInfo.startTime = DateTime.Now;
                                    alarmInfo.endTime = DateTime.Now;
                                    alarmInfo.description = string.Format("光栅数由[{0}]个变成[{1}]个", deviceValue.channelValues[i].gratingCount, wlData.chGratting[i].ngrating);
                                    TW_App.delegateCollection.SyncAlarm(alarmInfo);
                                    continue;
                                }

                                if (wlData.chGratting[i].ngrating == 0) continue;

                                for (int j = 0; j < wlData.chGratting[i].waveValueArray.Length; j++)
                                {
                                    if (Math.Abs(deviceValue.channelValues[i].gratingValues[j].preValue - wlData.chGratting[i].waveValueArray[j]) > TW_App.globalSetting.threshold.adjoinThreshold)
                                    {
                                        AlarmInfo alarmInfo = new AlarmInfo();
                                        alarmInfo.serialNo = serialNo;
                                        alarmInfo.type = AlarmType.ADJION;
                                        alarmInfo.key = (i + 1) + "_" + (j + 1) + "_" + ProcessStep.CONTINUOUS_DETECTION + "_" + AlarmType.ADJION;
                                        alarmInfo.channelNo = i + 1;
                                        alarmInfo.gratingNo = j + 1;
                                        alarmInfo.step = ProcessStep.CONTINUOUS_DETECTION;
                                        //alarmInfo.maxFullDiff = windowViewModel.values[i].diffValue;
                                        alarmInfo.maxDiff = deviceValue.channelValues[i].gratingValues[j].preValue - wlData.chGratting[i].waveValueArray[j];
                                        alarmInfo.startTime = DateTime.Now;
                                        alarmInfo.endTime = DateTime.Now;
                                        TW_App.delegateCollection.SyncAlarm(alarmInfo);
                                    }

                                    deviceValue.channelValues[i].gratingValues[j].preValue = wlData.chGratting[i].waveValueArray[j];
                                    if (deviceValue.channelValues[i].gratingValues[j].maxValue < wlData.chGratting[i].waveValueArray[j])
                                    {
                                        deviceValue.channelValues[i].gratingValues[j].maxValue = wlData.chGratting[i].waveValueArray[j];
                                    }
                                    if (deviceValue.channelValues[i].gratingValues[j].minValue > wlData.chGratting[i].waveValueArray[j])
                                    {
                                        deviceValue.channelValues[i].gratingValues[j].minValue = wlData.chGratting[i].waveValueArray[j];
                                    }

                                    if ((deviceValue.channelValues[i].gratingValues[j].maxValue - deviceValue.channelValues[i].gratingValues[j].minValue) > TW_App.globalSetting.threshold.adjoinThreshold)
                                    {
                                        AlarmInfo alarmInfo = new AlarmInfo();
                                        alarmInfo.serialNo = serialNo;
                                        alarmInfo.type = AlarmType.FULL;
                                        alarmInfo.key = (i + 1) + "_" + (j + 1) + "_" + ProcessStep.CONTINUOUS_DETECTION + "_" + AlarmType.FULL;
                                        alarmInfo.channelNo = i + 1;
                                        alarmInfo.gratingNo = j + 1;
                                        alarmInfo.step = ProcessStep.CONTINUOUS_DETECTION;
                                        alarmInfo.maxDiff = deviceValue.channelValues[i].gratingValues[j].maxValue - deviceValue.channelValues[i].gratingValues[j].minValue;
                                        alarmInfo.startTime = DateTime.Now;
                                        alarmInfo.endTime = DateTime.Now;
                                        TW_App.delegateCollection.SyncAlarm(alarmInfo);
                                    }
                                }
                            }
                        }

                    }


                    if ((DateTime.Now - nextRecordTime).TotalSeconds >= 60)
                    {
                        nextRecordTime = DateTime.Now;

                        double time = (DateTime.Now - startTime).TotalMinutes / 60;
                        TW_App.delegateCollection.SyncContinuousTime(serialNo, time);
                        if (time <= TW_App.globalSetting.continuousRunTime)
                        {
                            string msgStr = makeMsgData(msg);
                            sw.WriteLine(msgStr);
                        }
                        else
                        {
                            if (sw != null)
                            {
                                sw.Close();
                                sw = null;
                                try
                                {
                                    // 将烤机结束的波长数据复制到新文件
                                    string newFilePath = filePath.Replace("waveLen.txt", "waveLen_Finish.txt");
                                    FileInfo fileInfo = new FileInfo(filePath);
                                    fileInfo.CopyTo(newFilePath, true);
                                }
                                catch (Exception) { }

                            }
                        }
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
               
            }

            //Console.WriteLine((DateTime.Now - sssTime).TotalMilliseconds);
            //Console.WriteLine(iiindex);
            //iiindex++;
        }

        private string makeMsgData(QueueData msg)
        {
            Wave wlData = (Wave)msg; 
            //100个光栅数, 波长 XXXX.XXXX, 32个通道 
            StringBuilder stringBuilder = new StringBuilder(100 * 9 * 32);

            string tm = nextRecordTime.ToString("yyyy/MM/dd HH:mm:ss.fffffff");
            stringBuilder.AppendFormat("{0}\t", tm);

            foreach (var chData in wlData.chGratting) 
            {
                if (chData.ngrating == 0) continue;

                bool exists = true;//默认全部通道

                if (exists)
                {
                    stringBuilder.AppendFormat("{0}\t{1}\t", chData.chID + 1, chData.ngrating);


                    foreach (var v in chData.waveValueArray) 
                    {
                        stringBuilder.AppendFormat("{0}\t", v.ToString("f4"));//波长值
                    }
                    
                }

            }

            stringBuilder.Length--; //去掉最后一个逗号

            string line = stringBuilder.ToString();
            return line;
        }
    }
}
